home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #5 & #6
/
Amiga Plus CD - 1995 - No. 5 and 6.iso
/
pd
/
netz
/
magplip
/
source
/
port.asm
< prev
next >
Wrap
Assembly Source File
|
1995-08-20
|
11KB
|
315 lines
;
; $VER: port.asm 1.1 (20 Aug 1995)
;
; magplip.device - Parallel Line Internet Protocol
;
; Assembler routines for efficient port handling.
;
; Original code written by Oliver Wagner and Michael Balzer.
;
; This version has been completely reworked by Marius Gröger, introducing
; slight protocol changes. The new source is a lot better organized and
; maintainable.
;
; Additional changes and code cleanup by Jan Kratochvil and Martin Mares.
; The new source is significantly faster and yet better maintainable.
;
; (C) Copyright 1993-1994 Oliver Wagner & Michael Balzer
; (C) Copyright 1995 Marius Gröger
; (C) Copyright 1995 Jan Kratochvil & Martin Mares
; All Rights Reserved
;
; $HISTORY:
;
; 20 Aug 1995 : 001.001 : + removed need for conditional compiling, as we
; we want a generic, symmetrical code
; + in interrupt handlers, A6 points already to
; SysBase
; + using JSRLIB/JMPLIB macros
; + removed implicit some assumptions on the values
; behind symbolic names
; 13 Feb 1995 : 001.000 : created (in fact manually compiled from 'C'-
; original) (jk/mm)
;
section "text",code
IFND HARDARE_CIA_I
include "hardware/cia.i"
ENDC
IFND EXEC_MACROS_I
include "exec/macros.i"
ENDC
IFND MAGPLIP_I
include "magplip.i"
ENDC
ciaa equ $bfe001
ciab equ $bfd000
BaseA5 equ ciab+ciapra
xref _CRC16
xdef _interrupt
xdef _hwsend
xdef _hwrecv
;----------------------------------------------------------------------------
;
; NAME
; interrupt() - ICR FLG interrupt handler
;
; SYNOPSIS
; void interrupt(struct PLIPBase *)
; A1
;
; FUNCTION
; This is called from the CIA resource on the receipt of an Flag-
; interrupt. This is the case if the other side starts transmission
; and writes the first byte to our port.
; We recognise this here and propagate the information to the server
; task by Signal()ing it and by setting the PLIPB_RECEIVING bit
; in the flags field.
;
_interrupt:
btst #PLIPB_RECEIVING,pb_Flags(a1)
bne skipint
move.b pb_HandshakeBit+HS_LINE(a1),d0
btst d0,ciab+ciapra
beq skipint
bset #PLIPB_RECEIVING,pb_Flags(a1)
move.l pb_IntSigMask(a1),d0
move.l pb_Server(a1),a1
JMPLIB Signal
skipint rts
;----------------------------------------------------------------------------
;
; NAME
; hwsend() - low level send routine
;
; SYNOPSIS
; void hwsend(struct PLIPBase *)
; A0
;
; FUNCTION
; This routine sends the PLIPBase->pb_SendFrame to the other side. It
; cares for CRC encoding, if wanted.
;
_hwsend:
movem.l d2-d7/a2-a3/a5-a6,-(sp)
move.l a0,a2 ; a2 = PLIPBase
pea FALSE ; (sp) = return value
moveq #0,d3
move.l d3,d4
move.b pb_HandshakeBit+HS_REQUEST(a2),d3 ; d3 = HS_REQUEST
move.b pb_HandshakeBit+HS_LINE(a2),d4 ; d4 = HS_LINE
;
; CRC wanted ?
;
btst #PLIPB_SENDCRC,pb_Flags(a2)
beq hww_NoCRC
; yes
move.w #SYNCWORD_CRC,pb_SendFrame+pf_Sync(a2)
lea pb_SendFrame+pf_data(a2),a0
move.w pb_SendFrame+pf_Size(a2),d0
subq.w #PKTFRAMESIZE_2,d0
jsr _CRC16(pc)
move.w d0,pb_SendFrame+pf_CRC(a2)
bra.s hww_CRC
hww_NoCRC:
move.w #SYNCWORD_NOCRC,pb_SendFrame+pf_Sync(a2)
hww_CRC move.l pb_CIAABase(a2),a6
moveq #CIAICRF_FLG,d0
JSRLIB AbleICR ; DISABLEINT
lea BaseA5,a5
st ciaa+ciaddrb-BaseA5(a5) ; SETCIAOUTPUT
move.b (a5),d7 ; SAMPLEINPUT, d7 = State
lea pb_SendFrame(a2),a3
move.w pb_SendFrame+pf_Size(a2),d6
addq.w #PKTFRAMESIZE_1-2,d6
move.l pb_Timeout(a2),d5
move.b (a3)+,ciaa+ciaprb-BaseA5(a5) ; WRITECIA *p++
move.l d5,d2 ; initially we wait
add.l d2,d2 ; 2*Timeout
move.w d2,d1
swap d2
hww_LoopShake1:
move.b (a5),d0 ; ciab+ciapra
eor.b d7,d0
btst d4,d0 ; WAITINPUTTOGGLE
dbne d1,hww_LoopShake1
dbne d2,hww_LoopShake1
beq hww_TimedOut
eor.b d0,d7
hww_MainLoop:
move.b (a3)+,ciaa+ciaprb-BaseA5(a5) ; WRITECIA *p++
bchg d3,(a5) ; OUTPUTTOGGLE
move.l d5,d2
move.w d2,d1
swap d2
hww_LoopShake2:
move.b (a5),d0 ; ciab+ciapra
eor.b d7,d0
btst d4,d0 ; WAITINPUTTOGGLE
dbne d1,hww_LoopShake2
dbne d2,hww_LoopShake2
beq hww_TimedOut
eor.b d0,d7
dbra d6,hww_MainLoop
move.l #TRUE,(sp) ; rc = TRUE
hww_TimedOut:
sf ciaa+ciaddrb-BaseA5(a5) ; SETCIAINPUT
bclr d3,(a5) ; CLEARREQUEST ciab+ciapra
moveq #CIAICRF_FLG,d0
JSRLIB SetICR ; CLEARINT
move.w #CIAICRF_FLG|CIAICRF_SETCLR,d0
JSRLIB AbleICR ; ENABLEINT
move.l (sp)+,d0 ; return rc
movem.l (sp)+,d2-d7/a2-a3/a5-a6
Return rts
;----------------------------------------------------------------------------
;
; NAME
; hwrecv() - low level receive routine
;
; SYNOPSIS
; void hwrecv(struct PLIPBase *)
; A0
;
; FUNCTION
; This routine receives a magPLIP frame and stores it into
; PLIPBase->pb_ReceiveFrame. It cares for CRC decoding, if the incoming
; packet is encoded.
;
_hwrecv:
movem.l d2-d7/a2-a6,-(sp)
move.l a0,a2 ; a2 = PLIPBase
pea FALSE ; (sp) = return value
move.l pb_CIAABase(a2),a6 ; a6 = CIABase
move.l pb_Timeout(a2),a4 ; a4 = Timeout
moveq #0,d3
move.l d3,d5
move.b pb_HandshakeBit+HS_REQUEST(a2),d3 ; d3 = HS_REQUEST
move.b pb_HandshakeBit+HS_LINE(a2),d5 ; d5 = HS_LINE
lea BaseA5,a5 ; a5 = ciab+ciapra
moveq #CIAICRF_FLG,d0
JSRLIB AbleICR ; DISABLEINT
move.b (a5),d7 ; SAMPLEINPUT
cmp.b #SYNCBYTE_HEAD,ciaa+ciaprb-BaseA5(a5) ; READCIABYTE
bne hwr_TimedOut
bchg d3,(a5) ; OUTPUTTOGGLE
move.l a4,d2
move.w d2,d1
swap d2
hwr_LoopShake1:
move.b (a5),d0 ; ciab+ciapra
eor.b d7,d0
btst d5,d0 ; WAITINPUTTOGGLE
dbne d1,hwr_LoopShake1
dbne d2,hwr_LoopShake1
beq hwr_TimedOut
eor.b d0,d7
move.b ciaa+ciaprb-BaseA5(a5),d4 ; READCIABYTE
bchg d3,(a5) ; OUTPUTTOGGLE
move.b d4,d0
subq.b #SYNCBYTE_CRC,d0
subq.b #SYNCBYTE_NOCRC,d0
bcc hwr_TimedOut
lea pb_ReceiveFrame+pf_Size(a2),a3
; Read 1st length byte
;
move.l a4,d2
move.w d2,d1
swap d2
hwr_LoopShake2
move.b (a5),d0 ; ciab+ciapra
eor.b d7,d0
btst d5,d0 ; WAITINPUTTOGGLE
dbne d1,hwr_LoopShake2
dbne d2,hwr_LoopShake2
beq hwr_TimedOut
eor.b d0,d7
move.b ciaa+ciaprb-BaseA5(a5),(a3)+ ; READCIABYTE
bchg d3,(a5) ; OUTPUTTOGGLE
; Read 2nd length byte
;
move.l a4,d2
move.w d2,d1
swap d2
hwr_LoopShake3:
move.b (a5),d0 ; ciab+ciapra
eor.b d7,d0
btst d5,d0 ; WAITINPUTTOGGLE
dbne d1,hwr_LoopShake3
dbne d2,hwr_LoopShake3
beq hwr_TimedOut
eor.b d0,d7
move.b ciaa+ciaprb-BaseA5(a5),(a3)+ ; READCIABYTE
bchg d3,(a5) ; OUTPUTTOGGLE ciab+ciapra
move.w -2(a3),d6 ; = length
subq.w #PKTFRAMESIZE_2,d6
bcs hwr_TimedOut
cmp.w pb_MTU+2(a2),d6
bhi hwr_TimedOut
addq.w #PKTFRAMESIZE_2-1,d6
; Read main packet body
;
hwr_MainLoop:
move.l a4,d2
move.w d2,d1
swap d2
hwr_LoopShake4:
move.b (a5),d0 ; ciab+ciapra
eor.b d7,d0
btst d5,d0
dbne d1,hwr_LoopShake4
dbne d2,hwr_LoopShake4
beq hwr_TimedOut
eor.b d0,d7
move.b ciaa+ciaprb-BaseA5(a5),(a3)+ ; READCIABYTE
bchg d3,(a5) ; OUTPUTTOGGLE ciab+ciapra
dbra d6,hwr_MainLoop
hwr_DoneRead:
subq.b #SYNCBYTE_CRC,d4
bne hwr_ReadOkay
lea pb_ReceiveFrame+pf_data(a2),a0
move.w pb_ReceiveFrame+pf_Size(a2),d0
subq.w #PKTFRAMESIZE_2,d0
jsr _CRC16(pc)
cmp.w pb_ReceiveFrame+pf_CRC(a2),d0
bne hwr_TimedOut
hwr_ReadOkay:
move.l #TRUE,(sp)
hwr_TimedOut:
bclr #PLIPB_RECEIVING,pb_Flags(a2)
sf ciaa+ciaddrb-BaseA5(a5) ; SETCIAINPUT
bclr d3,(a5) ; CLEARREQUEST ciab+ciapra
moveq #CIAICRF_FLG,d0
JSRLIB SetICR ; CLEARINT
move.w #CIAICRF_FLG|CIAICRF_SETCLR,d0
JSRLIB AbleICR ; ENABLEINT
move.l (sp)+,d0 ; return value
movem.l (sp)+,d2-d7/a2-a6
rts
end